﻿// Made by Michiel van der Winden
// 1589615 TIV2A
// 26-03-2012

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;


namespace Team2_Vision
{
    class Resize : VisionAlgorithm
    {
        public Resize(String name) : base(name) { }
        public override System.Drawing.Bitmap DoAlgorithm(System.Drawing.Bitmap sourceImage, int hoi)
        {
            Bitmap returnImage = new Bitmap(sourceImage);
            returnImage = BoxBlur(returnImage);
            Image image = new Image(returnImage, ImageLockMode.ReadWrite);
            byte[] imgArray = image.array;

            for (int i = 0; i < (returnImage.Width * returnImage.Height * 3); i++)
            {
                if (imgArray[i] <= 100)
                {
                    imgArray[i] = 0;
                }

                else
                {
                    imgArray[i] = 255;
                }
            }

            returnImage = image.UnlockToBitmap();
            Bitmap returnImageWhite = returnImage;
            returnImage = IsolateLetter(returnImage);

            if (returnImage.Width == 80 && returnImage.Height == 100)
            {
                OCRAlgorithm OCR = new OCRAlgorithm();
                OCR.LineAlgorithm(returnImage);
                return sourceImage;
            }
            else
            {
                return returnImage;
            }
            return returnImage;
        }

        public Bitmap IsolateLetter(Bitmap source)
        {
            Image image = new Image(source, ImageLockMode.ReadWrite);
            byte[] imgArray = image.array;

            int x = 0, y = 0;
            int height = source.Height, width = source.Width;
            int north = height, east = 0, south = 0, west = width;

            for (int i = 0; i < (height * width * 3) - 15; i += 3)
            {
                x++;
                if (x == width)
                {
                    x = 0;
                    y++;
                }
                if (imgArray[i] == 0 && imgArray[i + 3] == 0)
                {
                    if (imgArray[i + 6] == 0 && imgArray[i + 9] == 0)
                    {
                        if (x < west)
                        {
                            west = x;
                        }
                        if (x > east)
                        {
                            east = x;
                        }
                        if (y < north)
                        {
                            north = y;
                        }
                        if (y > south)
                        {
                            south = y;
                        }
                    }
                }
            }

            if ((east - west) / (south - north) >= 1)
            {
                image.CutAndResize(0, 0, width, height, 90, 110);
                OCRForm.appendOutput('-');
            }

            else
            {
                image.CutAndResize(west+3, north+3, east - west - 5, south - north - 5, 80, 100);
            } 
            return image.UnlockToBitmap();;
        }

        public Bitmap BoxBlur(Bitmap sourceImage)
        {
            int srcWidth = sourceImage.Width % 4;

            if (sourceImage.Width % 4 != 0)
            {
                Image image = new Image(sourceImage, ImageLockMode.ReadWrite);
                image.CutAndResize(0, 0, sourceImage.Width + (4 - srcWidth), sourceImage.Height, sourceImage.Width + (4 - srcWidth), sourceImage.Height);
                sourceImage = image.UnlockToBitmap();
            }

            Bitmap returnImage = new Bitmap(sourceImage);

            BitmapData sourceImageData = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            BitmapData returnImageData = returnImage.LockBits(new Rectangle(0, 0, returnImage.Width, returnImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            IntPtr adressreturn = returnImageData.Scan0;
            IntPtr adresssource = sourceImageData.Scan0;

            int arraygrootte = sourceImage.Width * sourceImage.Height * 3;
            int matrix = 11;
            int midden = (matrix / 2);
            int teller = 0;
            int value = 0;

            byte[] array_from_source = new byte[arraygrootte];
            byte[] array_red = new byte[arraygrootte / 3];
            byte[] array_back = new byte[arraygrootte];
            int[] histogram = new int[256];


            Marshal.Copy(adresssource, array_from_source, 0, arraygrootte);

            //maak een array met alle rode waardes;

            for (int i = 0; i < arraygrootte / 3; i++)
            {
                array_red[i] = (byte)((array_from_source[i * 3] + array_from_source[(i * 3) + 1] + array_from_source[(i * 3) + 2]) / 3);
            }

            //zeker weten dat de histogram leeg is

            for (int i = 0; i < array_back.Length; i++)
            {
                array_back[i] = 255;
            }

            //select pixel
            for (int y = midden; y < sourceImage.Height - midden; y++)
            {
                teller = 0;
                //maak nieuwe matrix
                for (int my = -midden; my <= midden; my++)
                {
                    for (int mx = 0; mx < matrix; mx++)
                    {
                        teller += array_red[(((y + my) * sourceImage.Width) + mx)];
                    }
                }
                for (int x = midden + 1; x < sourceImage.Width - midden; x++)
                {
                    //matrix selecteren
                    for (int my = -midden; my <= midden; my++)
                    {
                        teller -= array_red[(((y + my) * sourceImage.Width) + x - midden - 1)];
                        teller += array_red[(((y + my) * sourceImage.Width) + x + midden)];
                    }
                    value = teller / (matrix * matrix);

                    //median terug zetten
                    array_back[((y * sourceImage.Width * 3) + x * 3)] = (byte)value;
                    array_back[((y * sourceImage.Width * 3) + x * 3) + 1] = (byte)value;
                    array_back[((y * sourceImage.Width * 3) + x * 3) + 2] = (byte)value;
                }
            }

            Marshal.Copy(array_back, 0, returnImageData.Scan0, arraygrootte);
            returnImage.UnlockBits(returnImageData);
            sourceImage.UnlockBits(sourceImageData);
            return returnImage;
        }
    }
}